package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.SubDic;
import cn.stylefeng.guns.modular.business.entity.CanalSecondClassify;
import cn.stylefeng.guns.modular.business.entity.CanalThreeClassify;
import cn.stylefeng.guns.modular.business.entity.EventsInfo;
import cn.stylefeng.guns.modular.business.enums.EventsInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.EventsInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.EventsInfoRequest;
import cn.stylefeng.guns.modular.business.service.CanalSecondClassifyService;
import cn.stylefeng.guns.modular.business.service.CanalThreeClassifyService;
import cn.stylefeng.guns.modular.business.service.EventsInfoService;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class EventsInfoServiceImpl extends ServiceImpl<EventsInfoMapper, EventsInfo> implements EventsInfoService {


    @Resource
    private SubUseBrowseService subUseBrowseService;
    @Resource
    private CanalThreeClassifyService canalThreeClassifyService;
    @Resource
    private CanalSecondClassifyService canalSecondClassifyService;
    @Resource
    private LoginUserApi loginUserApi;


    @Override
    public void add(EventsInfoRequest eventsInfoRequest) {
        EventsInfo eventsInfo = new EventsInfo();
        BeanUtil.copyProperties(eventsInfoRequest, eventsInfo);
        this.save(eventsInfo);
    }

    @Override
    public void del(EventsInfoRequest eventsInfoRequest) {

    }

    @Override
    public void edit(EventsInfoRequest eventsInfoRequest) {

    }

    @Override
    public EventsInfo detail(EventsInfoRequest eventsInfoRequest) {
        return this.queryCar(eventsInfoRequest);
    }

    @Override
    public PageResult<EventsInfo> findPage(EventsInfoRequest eventsInfoRequest) {
        LambdaQueryWrapper<EventsInfo> wrapper = createWrapper(eventsInfoRequest);
        Page<EventsInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public List<Map<String, Object>> findList(EventsInfoRequest eventsInfoRequest) {
        List<Map<String, Object>> eventsInfoList = new ArrayList<>();
        LambdaQueryWrapper<EventsInfo> queryWrapper = new LambdaQueryWrapper<>();

        String name = eventsInfoRequest.getTheCommon();
//        queryWrapper.like(ObjectUtil.isNotEmpty(name), EventsInfo::getEventsName, name);
        queryWrapper.like(ObjectUtil.isNotEmpty(name), EventsInfo::getTheCommon, name);
//        queryWrapper.like(ObjectUtil.isNotEmpty(name), EventsInfo::getHistoryDating, name);

       // LambdaQueryWrapper<EventsInfo> wrapper = this.createWrapper(eventsInfoRequest);
        //遍历list对象并添加新的key-value
        eventsInfoList = this.list(queryWrapper).stream().map(new Function<EventsInfo, Map<String, Object>>() {
            @Override
            public Map<String, Object> apply(EventsInfo eventsInfo) {
                Map<String, Object> map1 = new HashMap();
                String eventNames ="";
                String theCommon ="";
                String history ="";
                if(eventsInfo.getEventsName()!=null){
                    eventNames = eventsInfo.getEventsName();
                }
                if(eventsInfo.getHistoryDating()!=null){
                    history = eventsInfo.getHistoryDating();
                }
                if(eventsInfo.getTheCommon()!=null){
                    theCommon = eventsInfo.getTheCommon();
                }
                map1.put("eventsName",theCommon+history +eventNames);
                byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
                SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

                String jmid = YunHeKey.YHSJ +eventsInfo.getId();
                String encryptHex = aes.encryptHex(jmid);
                map1.put("id",encryptHex);
                return map1;
            }
        }).collect(Collectors.toList());

        return eventsInfoList ;
    }

    //@Override
    public List<Map<String,Object>> findAllList(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<EventsInfo> wrapper = createWrappers(riverList,townList,times,name);
        List<EventsInfo>  list = this.list(wrapper);
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(EventsInfo eventsInfo:list) {
            Map<String, Object> map = new HashMap<String, Object>();
//            Map<String, Object> map1 = new HashMap<String, Object>();
//            map = JSONObject.parseObject(JSONObject.toJSONString(eventsInfo), Map.class);
            String titleOne = eventsInfo.getTheCommon();
            if("".equals(eventsInfo.getTheCommon()) || eventsInfo.getTheCommon()==null){
                titleOne = eventsInfo.getHistoryDating();
            }
            if( eventsInfo.getEventsName() !=null){
                titleOne += eventsInfo.getEventsName();
            }
            map.put("title", titleOne);
            map.put("historyDating",eventsInfo.getHistoryDating());
            map.put("theCommon",eventsInfo.getTheCommon());
            map.put("from",eventsInfo.getEventsLaiyuanzhishu() );
            map.put("createTime",DateUtil.format(eventsInfo.getCreateTime(), "yyyy-MM-dd"));
            map.put("type",YunHeKey.YHSJ);
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

            String jmid = YunHeKey.YHSJ+eventsInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            mapList.add(map);
        }
        return mapList;
    }
    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<EventsInfo> createWrappers(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<EventsInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(name), EventsInfo::getEventsName, name).or()
                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventsSecond, name).or()
                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventsThree, name).or()
                .like(ObjectUtil.isNotNull(name), EventsInfo::getHistoryDating, name).or()
//                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventsRiver, name).or()
//                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventsFigure, name).or()
//                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventType, name).or()
                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventsZhushiyinyong, name).or());
//                .like(ObjectUtil.isNotNull(name), EventsInfo::getEventsPlace, name));
        if( !riverList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < riverList.size(); i++) {
                    String dicAname = riverList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicAname), EventsInfo::getEventsRiver, dicAname);
                    if (i != riverList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( !townList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < townList.size(); i++) {
                    String dicZname = townList.get(i).getDicZname();
                    String dicAname = townList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicZname), EventsInfo::getEventsPlace, dicZname).or()
                            .like(ObjectUtil.isNotEmpty(dicAname), EventsInfo::getEventsPlace, dicAname);
                    if (i != townList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( times.length !=0) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < times.length; i++) {
                    String time = times[i];
                    wrapper.like(ObjectUtil.isNotEmpty(time), EventsInfo::getEventsSecond, time);
                    if (i != times.length - 1) {
                        wrapper.or();
                    }
                }
            });
        }
//        for(int i=0 ;i<townList.size();i++) {
//            String dicZname = townList.get(i).getDicZname();
//            String dicAname = townList.get(i).getDicAname();
//            queryWrapper.like(ObjectUtil.isNotEmpty(dicZname), EventsInfo::getEventsPlace, dicZname);
//            queryWrapper.or();
//            queryWrapper.like(ObjectUtil.isNotEmpty(dicAname), EventsInfo::getEventsPlace, dicAname);
//            if(i !=townList.size()-1) {
//                queryWrapper.or();
//            }
//        }
//        for(int i=0 ;i<times.length;i++) {
//            String time = times[i];
//            queryWrapper.like(ObjectUtil.isNotEmpty(time), EventsInfo::getEventsSecond, time);
//            if(i !=times.length-1) {
//                queryWrapper.or();
//            }
//        }
        return queryWrapper;
    }

    @Override
    public Map<String, Object> toEventReview(String jmId) {
        byte[] key =YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String decryptStr = aes.decryptStr(jmId, CharsetUtil.CHARSET_UTF_8);
        //获取ID字符串YHSJ后面真实的的id
        String id = StrUtil.subAfter(decryptStr,YunHeKey.YHSJ,false);
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid;
        if (ObjectUtil.isNotNull(request)) {
            LoginUser loginUser = LoginContext.me().getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(EventsInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<EventsInfo> queryWrapper = new LambdaQueryWrapper<>();
        if ("".equals(id)) {
            Map<String, Object> mapLists = new HashMap<>();
//            Map<String, Object> map =new HashMap<>();
//            map.put("error","id为空");
            return mapLists;
        }
        queryWrapper.eq(ObjectUtil.isNotEmpty(id), EventsInfo::getId, id);
        List<EventsInfo> eventsInfoList = this.list(queryWrapper);

//        YunHeUtil.saveBrowse(YunHeKey.DASHIJI,eventsInfoList.get(0).getEventsName(),userid);
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (EventsInfo eventsInfo : eventsInfoList) {

            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(eventsInfo), Map.class);

            // 获取类的属性
            Field[] declaredFields = EventsInfo.class.getDeclaredFields();
            List<Map<String, Object>> mplist = new ArrayList<>();
            // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
            if (declaredFields.length != 0) {
                String title = "";
                int i = 1;
                Map<String, Object> p = new HashMap<String, Object>();
                for (Field field : declaredFields) {

                    Map<String, Object> mp = new HashMap<String, Object>();
                    if (field.getAnnotation(ApiModelProperty.class) != null) {
                        //获取注解属性
                        ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                        // key和value可根据需求存
                        // 这存的key为注解的值，value为类属性名
                        if ("theCommon".equals(field.getName()) || "historyDating".equals(field.getName()) || "eventsName".equals(field.getName())) {
                            if(map.get(field.getName()) != null) {
                                title += map.get(field.getName()) + "-";
                            }
                        }

                        if ("eventsIntroduce".equals(field.getName()) || "eventsZhushiyinyong".equals(field.getName())) {
                            if("eventsZhushiyinyong".equals(field.getName())){
                                p.put("annotation", map.get(field.getName()));
                            }else {
                                p.put(field.getName(), map.get(field.getName()));
                            }
                        } else {
                            mp.put("key", aa.value());
                            mp.put("value", map.get(field.getName()));

                            if (i != 1) {
                                mplist.add(mp);
                            }
                        }

                    }
                    i++;
                }
                String tt = StrUtil.sub(title,0,title.length()-1);
                p.put("title",tt);
                p.put("list", mplist);
                if (i != 1) {
                    mapList.add(p);
                }
            }
        }
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.DASHIJI,mapList.get(0).get("title").toString(),userid,request);
        }
        return mapList.get(0);

    }

    /**
     * 获取信息
     */
    private EventsInfo queryCar(EventsInfoRequest eventsInfoRequest) {
        EventsInfo eventsInfo = this.getById(eventsInfoRequest.getId());
        if (ObjectUtil.isEmpty(eventsInfo)) {
            return null;
        }
        return eventsInfo;
    }

    /**
     * 创建查询wrapper
     */
    private LambdaQueryWrapper<EventsInfo> createWrapper(EventsInfoRequest eventsInfoRequest) {
        LambdaQueryWrapper<EventsInfo> queryWrapper = new LambdaQueryWrapper<>();

        String name = eventsInfoRequest.getEventsName();
        queryWrapper.like(ObjectUtil.isNotEmpty(name), EventsInfo::getEventsName, name);

        return queryWrapper;
    }

    /**
     * 获取二级页面点击展开的详细数据
     *
     * @param canalThreeClassify
     * @return
     */
    @Override
    public List<Map<String, Object>> getThreeList(CanalThreeClassify canalThreeClassify) {
        //List<Map<String,Object>> eventsInfoList = new ArrayList<>();
        List<Map<String, Object>> mapList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        //从三级分类获取二级的Code
        List<CanalThreeClassify> canalThreeClassifyList = canalThreeClassifyService.findThreeList(canalThreeClassify);
        for (int i = 0; i < canalThreeClassifyList.size(); i++) {
            Map<String, Object> mapa = new HashMap<>();
            List<Map<String, Object>> mapList1 = new ArrayList<>();
            String SecondNameCode = canalThreeClassifyList.get(i).getCanalSecondClassifyCode();
            String threename = canalThreeClassifyList.get(i).getCanalThreeClassifyName();
            LambdaQueryWrapper<CanalSecondClassify> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ObjectUtil.isNotEmpty(SecondNameCode), CanalSecondClassify::getCanalSecondClassifyCode, SecondNameCode);
            List<CanalSecondClassify> canalSecondClassifyList = canalSecondClassifyService.list(queryWrapper);

            // LambdaQueryWrapper<EventsInfo> eventWrapper = new LambdaQueryWrapper<>();

            // eventWrapper.eq(ObjectUtil.isNotEmpty(canalSecondClassifyList.get(0).getCanalSecondClassifyName()), EventsInfo::getEventsSecond, canalSecondClassifyList.get(0).getCanalSecondClassifyName());

            //eventWrapper.eq(ObjectUtil.isNotEmpty(threename), EventsInfo::getEventsThree, threename);
            LambdaQueryWrapper<EventsInfo> eventWrapper = new LambdaQueryWrapper<>();

            eventWrapper.eq(ObjectUtil.isNotEmpty(threename), EventsInfo::getEventsThree, threename);

            List<EventsInfo> eventsInfos = this.list(eventWrapper);

            //mapList1.addAll(eventsInfos);
            mapList1 = eventsInfos.stream().map(new Function<EventsInfo, Map<String, Object>>() {
                @Override
                public Map<String, Object> apply(EventsInfo eventsInfo) {
                    Map<String, Object> map1 = new HashMap();
                    map1.put("historyDating", eventsInfo.getHistoryDating());
                    map1.put("theCommon", eventsInfo.getTheCommon());
                    map1.put("eventsName", eventsInfo.getEventsName());
                    byte[] key =YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
                    SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

                    String jmid = YunHeKey.YHSJ+eventsInfo.getId();
                    String encryptHex = aes.encryptHex(jmid);
                    map1.put("id",encryptHex);
                    return map1;
                }
            }).collect(Collectors.toList());
            mapa.put("threeList", mapList1);
            mapa.put("canalThreeClassifyName", threename);
            if (!eventsInfos.isEmpty()) {
                mapList.add(mapa);
            }

        }
        //  LambdaQueryWrapper<EventsInfo> wrapper = this.createWrapper(eventsInfoRequest);
        return mapList;
    }

}
